﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;

namespace YRevitJig
{
	public class XUiJigBase : WndMsgManager, IDisposable
	{
		public XUiJigBase(UIDocument uiDoc) : base(uiDoc)
		{
			base.OnMouseActivity += this.OnMouseActivity;
			this.OnPaintEvent = (PaintEventHandler)Delegate.Combine(this.OnPaintEvent, new PaintEventHandler(this.OnPaint));
			this.OnKeyDownEvent = (KeyEventHandler)Delegate.Combine(this.OnKeyDownEvent, new KeyEventHandler(this.OnKeyDown));
			this.OnFocusEvent = (WndMsgManager.FocusChangeEvent)Delegate.Combine(this.OnFocusEvent, new WndMsgManager.FocusChangeEvent(this.OnFocusChangeEvent));
		}

		public new void Dispose()
		{
			base.Dispose();
			base.OnMouseActivity -= this.OnMouseActivity;
			this.OnPaintEvent = (PaintEventHandler)Delegate.Remove(this.OnPaintEvent, new PaintEventHandler(this.OnPaint));
			this.OnKeyDownEvent = (KeyEventHandler)Delegate.Remove(this.OnKeyDownEvent, new KeyEventHandler(this.OnKeyDown));
			this.OnFocusEvent = (WndMsgManager.FocusChangeEvent)Delegate.Remove(this.OnFocusEvent, new WndMsgManager.FocusChangeEvent(this.OnFocusChangeEvent));
			bool flag = this.m_prompDlg != null;
			if (flag)
			{
				this.m_prompDlg.Dispose();
				this.m_prompDlg = null;
			}
		}

		public void SetPromptState(string strPrompt, bool bShowPrompt, bool bShowInput)
		{
			bool flag = bShowPrompt || bShowInput;
			if (flag)
			{
				bool flag2 = this.m_hMDIActiveChildClientWnd == IntPtr.Zero;
				if (!flag2)
				{
					bool flag3 = this.m_prompDlg == null;
					if (flag3)
					{
						System.Drawing.Color viewBackgroundReverseColor = RevitVersionFuncs.GetViewBackgroundReverseColor(base.UiDoc.Application.Application);
						this.m_prompDlg = new PromptDlg(this.m_hMDIActiveChildClientWnd, viewBackgroundReverseColor);
					}
					this.m_prompDlg.SetDlgState(strPrompt, bShowPrompt, bShowInput);
				}
			}
			else
			{
				bool flag4 = this.m_prompDlg != null;
				if (flag4)
				{
					this.m_prompDlg.Dispose();
					this.m_prompDlg = null;
				}
			}
		}

		public static int TwoPointDist(System.Drawing.Point pt1, System.Drawing.Point pt2)
		{
			int num = pt1.X - pt2.X;
			int num2 = pt1.Y - pt2.Y;
			return (int)Math.Sqrt((double)(num * num + num2 * num2));
		}

		public static double TwoPointAngle(System.Drawing.Point ptFrom, System.Drawing.Point ptTo)
		{
			int num = ptTo.X - ptFrom.X;
			int num2 = ptTo.Y - ptFrom.Y;
			bool flag = num == 0;
			double result;
			if (flag)
			{
				result = ((num2 > 0) ? 4.71238898038469 : Math.PI*.5);
			}
			else
			{
				double num3 = (double)num2 / (double)num;
				double num4 = Math.Atan(-num3);
				bool flag2 = num4 < 0.0;
				if (flag2)
				{
					num4 += Math.PI*2;
				}
				result = num4;
			}
			return result;
		}

		public static System.Drawing.Point OffsetPoint(System.Drawing.Point ptFrom, double dAngle, int nDistance)
		{
			int num = (int)((double)nDistance * Math.Cos(dAngle));
			int num2 = (int)((double)nDistance * Math.Sin(dAngle));
			System.Drawing.Point result = new System.Drawing.Point(ptFrom.X + num, ptFrom.Y - num2);
			return result;
		}

		public static void SortTwoPoint(ref System.Drawing.Point pt1, ref System.Drawing.Point pt2)
		{
			bool flag = pt1.X == pt2.X;
			if (flag)
			{
				bool flag2 = pt1.Y < pt2.Y;
				if (flag2)
				{
					System.Drawing.Point point = pt1;
					pt1 = pt2;
					pt2 = point;
				}
			}
			else
			{
				bool flag3 = pt1.X > pt2.X;
				if (flag3)
				{
					System.Drawing.Point point2 = pt1;
					pt1 = pt2;
					pt2 = point2;
				}
			}
		}

		public System.Drawing.Point Revit2Client(XYZ point)
		{
			try
			{
				System.Drawing.Point result = this.Revit2Screen(point);
				JigFuncs.Screen2Client(base.JigForm.Handle, ref result);
				return result;
			}
			catch
			{
			}
			return System.Drawing.Point.Empty;
		}

		public XYZ Client2Revit(System.Drawing.Point point)
		{
			try
			{
				JigFuncs.Client2Screen(base.JigForm.Handle, ref point);
				return this.Screen2Revit(point);
			}
			catch
			{
			}
			return null;
		}

		public System.Drawing.Point Revit2Screen(XYZ point)
		{
			try
			{
				int num = 0;
				int num2 = 0;
				int num3 = 0;
				int num4 = 0;
				RevitViewExtension.GetRevitWndRectangle(base.UiViewActive, ref num, ref num2, ref num3, ref num4);
				Transform inverse = base.ViewActive.CropBox.Transform.Inverse;
				IList<XYZ> zoomCorners = base.UiViewActive.GetZoomCorners();
				XYZ xyz = inverse.OfPoint(point);
				XYZ xyz2 = inverse.OfPoint(zoomCorners[0]);
				XYZ xyz3 = inverse.OfPoint(zoomCorners[1]);
				double num5 = (double)(num3 - num) / (xyz3.X - xyz2.X);
				int x = num + (int)((xyz.X - xyz2.X) * num5);
				int y = num2 + (int)((xyz3.Y - xyz.Y) * num5);
				return new System.Drawing.Point(x, y);
			}
			catch
			{
			}
			return System.Drawing.Point.Empty;
		}

		public XYZ Screen2Revit(System.Drawing.Point point)
		{
			try
			{
				int num = 0;
				int num2 = 0;
				int num3 = 0;
				int num4 = 0;
				RevitViewExtension.GetRevitWndRectangle(base.UiViewActive, ref num, ref num2, ref num3, ref num4);
				Transform inverse = base.ViewActive.CropBox.Transform.Inverse;
				IList<XYZ> zoomCorners = base.UiViewActive.GetZoomCorners();
				XYZ xyz = inverse.OfPoint(zoomCorners[0]);
				XYZ xyz2 = inverse.OfPoint(zoomCorners[1]);
				double num5 = (xyz2.Y - xyz.Y) / (double)(num4 - num2);
				double num6 = xyz.X + (double)(point.X - num) * num5;
				double num7 = xyz.Y + (double)(num4 - point.Y) * num5;
				XYZ xyz3 = new XYZ(num6, num7, 0.0);
				Transform transform = base.ViewActive.CropBox.Transform;
				return transform.OfPoint(xyz3);
			}
			catch
			{
			}
			return null;
		}

		private new void OnMouseActivity(object sender, MouseEventArgs mouseEvent)
		{
			this.m_ptCur = mouseEvent.Location;
			bool flag = this.m_prompDlg != null;
			if (flag)
			{
				Size size = new Size(2, 2);
				System.Drawing.Point ptCur = this.m_ptCur;
				JigFuncs.Client2Screen(base.JigForm.Handle, ref ptCur);
				bool flag2 = base.JigForm.Left >= ptCur.X || base.JigForm.Right <= ptCur.X || base.JigForm.Top >= ptCur.Y || base.JigForm.Bottom <= ptCur.Y;
				if (flag2)
				{
					this.m_prompDlg.DlgVisible(false);
				}
				else
				{
					bool flag3 = base.JigForm.Right - ptCur.X < this.m_prompDlg.Width + size.Width;
					if (flag3)
					{
						int num = this.m_prompDlg.Width + size.Width - (base.JigForm.Right - ptCur.X);
						this.m_prompDlg.Location = new System.Drawing.Point(ptCur.X + size.Width - num, ptCur.Y - this.m_prompDlg.Height - size.Height);
						this.m_prompDlg.DlgVisible(true);
					}
					else
					{
						this.m_prompDlg.Location = new System.Drawing.Point(ptCur.X + size.Width, ptCur.Y - this.m_prompDlg.Height - size.Height);
						this.m_prompDlg.DlgVisible(true);
					}
				}
				bool flag4 = this.m_prompDlg.Visible && this.m_prompDlg.MouseMoveArgs != null;
				if (flag4)
				{
					this.m_prompDlg.MouseMoveArgs();
				}
			}
		}

		private void OnKeyDown(object sender, KeyEventArgs e)
		{
			this.Key(e);
			bool flag = this.m_prompDlg != null && this.m_prompDlg.Visible;
			if (flag)
			{
				this.m_prompDlg.OnKeyDown(sender, e);
			}
		}

		private void OnFocusChangeEvent(object sender, bool bHadFocus)
		{
			bool flag = this.m_prompDlg != null && this.m_prompDlg.Visible;
			if (flag)
			{
				this.m_prompDlg.OnFocusChangeEvent(sender, bHadFocus);
			}
		}

		private void OnPaint(object sender, PaintEventArgs e)
		{
			bool flag = base.ViewActive is ViewDrafting;
			if (flag)
			{
				this.Draw(e);
			}
			else
			{
				XYZ xyz = base.ViewActive.ViewDirection.Normalize();
				XYZ normal = base.SketchPlane.GetPlane().Normal;
				bool flag2 = normal.IsAlmostEqualTo(xyz) || normal.IsAlmostEqualTo(xyz.Negate());
				if (flag2)
				{
					this.Draw(e);
				}
			}
		}

		public void EndCommand()
		{
			byte bVk = 27;
			int dwFlags = 0;
			int dwFlags2 = 2;
			DllImportManeger.keybd_event(bVk, 0, dwFlags, 0);
			DllImportManeger.keybd_event(bVk, 0, dwFlags2, 0);
		}

		public virtual void Draw(PaintEventArgs paintEventArgs)
		{
		}

		public virtual void Key(KeyEventArgs keyArg)
		{
			bool flag = keyArg.KeyCode == Keys.Return;
			if (flag)
			{
				bool flag2 = this.m_prompDlg != null && !string.IsNullOrEmpty(this.m_prompDlg.GetInputValue());
				if (flag2)
				{
					this.CmdEndType = XUiJigBase.ECmdEndType.eEnter;
					this.EndCommand();
				}
			}
			else
			{
				bool flag3 = keyArg.KeyCode == Keys.Escape;
				if (flag3)
				{
					this.CmdEndType = XUiJigBase.ECmdEndType.eEscape;
				}
				else
				{
					this.CmdEndType = XUiJigBase.ECmdEndType.eOther;
				}
			}
		}

		public virtual List<Curve> CreateCurves()
		{
			return null;
		}

		public void DrawAxisLine(Graphics graphis, XYZ ptBase1, XYZ ptBase2)
		{
			double num = 50.0 * JigFuncs.RevitToScreenScale(base.UiViewActive, base.ViewActive);
			XYZ xyz = (ptBase2 - ptBase1).Normalize();
			XYZ point = ptBase1 - xyz * num;
			XYZ point2 = ptBase2 + xyz * num;
			System.Drawing.Point ptStart = this.Revit2Client(ptBase1);
			System.Drawing.Point ptStart2 = this.Revit2Client(ptBase2);
			System.Drawing.Point ptEnd = this.Revit2Client(point);
			System.Drawing.Point ptEnd2 = this.Revit2Client(point2);
			Pen pen = new Pen(base.JigPen.Color, base.JigPen.Width);
			pen.DashStyle = DashStyle.Dash;
			XGraphics g = new XGraphics(graphis, pen);
			XLine2D xline2D = new XLine2D(ptStart, ptEnd);
			XLine2D xline2D2 = new XLine2D(ptStart2, ptEnd2);
			xline2D.Draw(g);
			xline2D2.Draw(g);
			pen.Dispose();
		}

		public XUiJigBase.ECmdEndType CmdEndType { get; set; }

		public PromptDlg m_prompDlg = null;

		protected System.Drawing.Point m_ptCur = System.Drawing.Point.Empty;

		public enum EJigResult
		{
			eRtUnknown,
			eRtOk,
			eRtCancel
		}

		public enum EResetPoint
		{
			eNoOper,
			eByAngle,
			eByOrtho,
			eByAxis
		}

		public enum ECmdEndType
		{
			eOther,
			eEscape,
			eEnter,
			eKeyWord
		}
	}
}
